import json
import os


def load_json(file_path):
    f = open(file_path, 'r')
    content = f.read()
    a = json.loads(content)
    f.close()
    return a


def generateRepoTableName(destFilePath, dbTableName):
    alter(destFilePath, "$table_name$", dbTableName)


def generateRepoStructName(destFilePath, bigHumpName, smallHumpName):
    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$xxxxxx$", smallHumpName)


def generateRepoFields(destFilePath, fields):
    # 替换结构体字段区域
    struct_field_loop_area = ""
    for field in fields:
        bigField = field["bigField"]
        dbType = field["type"]
       # 获取描述信息，如果没有则使用空字符串
        desc = field.get("desc", "")
        # 默认string
        type = "string"
        if dbType.find("int") != -1:
            type = "int64"
        if dbType.find("decimal") != -1:
            type = "float64"
        #struct_field_loop_area += "%s\t%s\n\t" % (bigField, type)
        struct_field_loop_area += "%s\t%s\t//%s\n\t" % (bigField, type, desc)

    print(struct_field_loop_area)
    alter(destFilePath, "$struct_field_loop_area$", struct_field_loop_area)


def generateRepoCondition(destFilePath, fields):
    condition_loop_area = ""
    simple_list_query_field_loop_area = ""
    for field in fields:
        bigField = field["bigField"]
        columnName = field["columnName"]
        dbType = field["type"]

        sub_area = ""
        if dbType.find("int") != -1:
            sub_area += "if param.%s != 0 {" % bigField
            sub_area += '\t\tconditions = append(conditions, repository.NewAndCondition("%s = ?", param.%s))' % (
            columnName, bigField)
            sub_area += "\t}"
        if dbType.find("varchar") != -1:
            sub_area += 'if param.%s != "" {\n' % bigField
            sub_area += '\t\tconditions = append(conditions, repository.NewAndCondition("%s = ?", param.%s))\n' % (
            columnName, bigField)
            sub_area += "\t}\n"
        if dbType.find("decimal") != -1:
            sub_area += 'if param.%s != 0.00 {\n' % bigField
            sub_area += '\t\tconditions = append(conditions, repository.NewAndCondition("%s = ?", param.%s))\n' % (
            columnName, bigField)
            sub_area += "\t}\n"

        condition_loop_area += "%s\n\t" % (sub_area)


        simple_list_query_field_loop_area += 'if param.%s != "" {\n\t\t \
            conditions = append(conditions, "%s = ?")\n\t\t \
            params = append(params, param.%s)\n \
        }\n\t' % (bigField, columnName ,bigField)

    print(condition_loop_area)
    alter(destFilePath, "$condition_loop_area$", condition_loop_area)
    alter(destFilePath, "$simple_list_query_field_loop_area$", simple_list_query_field_loop_area)


# 字符串替换
def alter(file, old_str, new_str):
    file_data = ""
    with open(file, "r", encoding="utf-8") as f:
        for line in f:
            if old_str in line:
                line = line.replace(old_str, new_str)
            file_data += line
    with open(file, "w", encoding="utf-8") as f:
        f.write(file_data)


# 生成repo
def generateAppRepo(dbTableName, bigHumpName, smallHumpName, fields):
    # 目标文件
    destFilePath = "./generate/repo/%s" % repoFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)

    # 复制文件
    cpRepoCmd = "cp ./template/repo_template %s" % destFilePath
    os.system(cpRepoCmd)

    generateRepoTableName(destFilePath, dbTableName)
    generateRepoStructName(destFilePath, bigHumpName, smallHumpName)
    generateRepoFields(destFilePath, fields)
    generateRepoCondition(destFilePath, fields)

# 生成 thrift 方法
def generateAppThrift(fields, thriftFileName):
    # 目标文件
    destFilePath = "./generate/thrift/%s" % thriftFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)

    # 复制文件
    cpRepoCmd = "cp ./template/thrift_template %s" % destFilePath
    os.system(cpRepoCmd)

    # 替换结构体字段区域
    struct_field_loop_area = ""
    idx = 8

    # struct_field_loop_area += "%d: i64 id\n" % (idx)
    # idx += 1
    #
    # struct_field_loop_area += "\t%d: binary createdAt\n" % (idx)
    # idx += 1
    #
    # struct_field_loop_area += "\t%d: binary updatedAt\n" % (idx)
    # idx += 1

    for field in fields:
        smallField = field["smallField"]
        dbType = field["type"]
        # 默认string
        type = "string"
        if dbType.find("int") != -1:
            type = "i64"
        if dbType.find("decimal") != -1:
            type = "double"
        struct_field_loop_area += "\t%d: %s %s\n" % (idx+1, type, smallField)
        idx += 1

    print(struct_field_loop_area)
    alter(destFilePath, "$struct_field_loop_area$", struct_field_loop_area)
    alter(destFilePath, "$XXXXXX$", bigHumpName)


def generateAppService(fields):
    # 目标文件
    destFilePath = "./generate/service/%s" % serviceFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)

    # 复制文件
    cpRepoCmd = "cp ./template/service_template %s" % destFilePath
    os.system(cpRepoCmd)

    struct_field_loop_area = ""
    query_field_loop_area = ""
    for field in fields:
        bigField = field["bigField"]
        query_field_loop_area += "%s: req.Data.%s,\n\t\t\t" % (bigField, bigField)
        struct_field_loop_area += "%s: data.%s,\n\t" % (bigField, bigField)

    print(struct_field_loop_area)
    alter(destFilePath, "$query_field_loop_area$", query_field_loop_area)
    alter(destFilePath, "$struct_field_loop_area$", struct_field_loop_area)
    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$xxxxxx$", smallHumpName)


def generateBffRouter(bigHumpName, smallHumpName, fields):
    # 目标文件
    destFilePath = "./generate/router/%s" % bffRouterFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)

    # 复制文件
    cpRepoCmd = "cp ./template/router_template %s" % destFilePath
    os.system(cpRepoCmd)

    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$xxxxxx$", smallHumpName)


def generateBffHandle(bigHumpName, smallHumpName, fields):
    # 目标文件
    destFilePath = "./generate/handler/%s" % bffHandlerFileName
    # 清理文件 
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)

    # 复制文件
    cpRepoCmd = "cp ./template/handler_template %s" % destFilePath
    os.system(cpRepoCmd)

    struct_field_loop_area = ""
    query_field_loop_area = ""
    for field in fields:
        bigField = field["bigField"]
        query_field_loop_area += "%s: req.%s,\n\t" % (bigField, bigField)
        struct_field_loop_area += "%s: data.%s,\n\t" % (bigField, bigField)

    print(query_field_loop_area)
    alter(destFilePath, "$query_field_loop_area$", query_field_loop_area)
    alter(destFilePath, "$struct_field_loop_area$", struct_field_loop_area)
    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$xxxxxx$", smallHumpName)

def generateBffHandleStruct(bigHumpName, smallHumpName, fields):
    # 目标文件
    destFilePath = "./generate/handler/struct_%s" % bffHandlerFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)

    # 复制文件
    cpRepoCmd = "cp ./template/handler_struct_template %s" % destFilePath
    os.system(cpRepoCmd)

    struct_field_loop_area = ""
    for field in fields:
        bigField = field["bigField"]
        smallField = field["smallField"]
		# 获取描述信息，如果没有则使用空字符串
        desc = field.get("desc", "")
        dbType = field["type"]
        # 默认string
        type = "string"
        if dbType.find("int") != -1:
            type = "int64"
        if dbType.find("decimal") != -1:
            type = "float64"

        # Chinese      string `json:"chinese" form:"chinese"`
        struct_field_loop_area += "%s %s `json:\"%s\" form:\"%s\"`\t//%s\n\t" % (bigField, type, smallField, smallField,desc)
		
    print(struct_field_loop_area)
    alter(destFilePath, "$struct_field_loop_area$", struct_field_loop_area)
    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$xxxxxx$", smallHumpName)


def generateGateway(bigHumpName,smallHumpName, bffPort, bizName, routerGroup):
    # 目标文件
    destFilePath = "./generate/gateway/%s" % gatewayFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)

    # 复制文件
    cpRepoCmd = "cp ./template/gateway_template %s" % destFilePath
    os.system(cpRepoCmd)

    alter(destFilePath, "$xxxxxx$", smallHumpName)
    alter(destFilePath, "$port$", bffPort)
    alter(destFilePath, "$bizName$", bizName)
    alter(destFilePath, "$routerGroup$", routerGroup)
    alter(destFilePath, "$XXXXXX$", bigHumpName)


def generateRole(bigHumpName,smallHumpName, parentModuleName, parentModuleCode, bizName, routerGroup, roleNodeCode):
    # 目标文件
    destFilePath = "./generate/role/%s" % roleFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)

    # 复制文件
    cpRepoCmd = "cp ./template/role_template %s" % destFilePath
    os.system(cpRepoCmd)

    alter(destFilePath, "$xxxxxx$", smallHumpName)
    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$parentModuleName$", parentModuleName)
    alter(destFilePath, "$parentModuleCode$", parentModuleCode)
    alter(destFilePath, "$bizName$", bizName)
    alter(destFilePath, "$routerGroup$", routerGroup)
    alter(destFilePath, "$roleNodeCode$", roleNodeCode)


def generateVue(bigHumpName, smallHumpName, fields):
    # ================ vue 页面 ======================
    generateVuePage(bigHumpName, smallHumpName, fields)

    # ================ store js ======================
    generateVueStoreJS(bigHumpName, smallHumpName, fields)

    # ================ api js   ======================
    generateVueApiJS(bigHumpName, smallHumpName, fields)


def generateVuePage(bigHumpName, smallHumpName, fields):
    # 目标文件
    destFilePath = "./generate/vue/%s" % vueFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)
    # 复制文件
    cpRepoCmd = "cp ./template/vue/page_template.vue %s" % destFilePath
    os.system(cpRepoCmd)
    filter_field_loop_area = ""
    data_list_field_loop_area = ""
    edit_list_field_loop_area = ""
    for field in fields:
        smallField = field["smallField"]
        desc = field["desc"]
        # <InputText v-model="store.filter.chinese.value" placeholder="中文" class="w-2 mr-2"/>
        filter_field_loop_area += '<InputText v-model="store.filter.%s.value" placeholder="%s" />\n\t' % (
        smallField, desc)

        #  <Column field="chinese" header="中文"   headerStyle="width:15%; min-width:12rem;">
        #             <template #body="{data}">
        #               {{data.chinese}}
        #             </template>
        #           </Column>

        data_list_field_loop_area += '<Column field="%s" header="%s" Style="%s" > \n' \
                                     '  <template #body="{data}"> \n  ' \
                                     '      {{data.%s}} \n ' \
                                     '  </template> \n ' \
                                     '</Column>\n\t' % (smallField, desc,"min-width: 150px", smallField)

        # <div class="field mr-3">
        #             <label>中文</label><label class="required-icon">*</label>
        #             <InputText v-model.trim="store.form.chinese" required="true" class="w-12 flex" :class="{'p-invalid': submitted && !store.form.chinese}"  />
        #             <small class="p-error" v-if="submitted && !store.form.chinese">{{ $t("common.name") }}{{ $t("common.isRequired") }}</small>
        #           </div>

        edit_list_field_loop_area += '<div class="field mr-3">\n' \
                                     '  <label>%s</label><label class="required-icon">*</label>\n' \
                                     '      <InputText v-model.trim="store.form.%s" required="true" class="w-12 flex" :class="{\'p-invalid\': submitted && !store.form.%s}"  />\n' \
                                     '      <small class="p-error" v-if="submitted && !store.form.%s">%s必填</small>' \
                                     '</div>' % (desc, smallField, smallField, smallField, desc)
    alter(destFilePath, "$filter_field_loop_area$", filter_field_loop_area)
    alter(destFilePath, "$data_list_field_loop_area$", data_list_field_loop_area)
    alter(destFilePath, "$edit_list_field_loop_area$", edit_list_field_loop_area)
    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$roleNodeCode$", roleNodeCode)
    alter(destFilePath, "$vueStoreFileName$", vueStoreFileName)

def generateVueStoreJS(bigHumpName, smallHumpName, fields):
    # 目标文件
    destFilePath = "./generate/vue/%s" % vueStoreFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)
    # 复制文件
    cpRepoCmd = "cp ./template/vue/store_template.js %s" % destFilePath
    os.system(cpRepoCmd)

    filter_field_loop_area = ""
    form_field_loop_area = ""
    query_field_loop_area = ""
    for field in fields:
        smallField = field["smallField"]
        desc = field["desc"]
        #
        # this.id = {value: null}
        filter_field_loop_area += 'this.%s = {value: null}\n\t\t' % (smallField)

        # this.id = null
        form_field_loop_area += 'this.%s = null\n\t\t' % (smallField)

        # chinese: this.filter.chinese.value,
        query_field_loop_area += '%s: this.filter.%s.value,\n\t\t\t\t\t' % (smallField, smallField)


    alter(destFilePath, "$filter_field_loop_area$", filter_field_loop_area)
    alter(destFilePath, "$form_field_loop_area$", form_field_loop_area)
    alter(destFilePath, "$query_field_loop_area$", query_field_loop_area)

    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$xxxxxx$", smallHumpName)
    alter(destFilePath, "$vueApiFileName$", smallHumpName)

def generateVueApiJS(bigHumpName, smallHumpName, fields):
    # 目标文件
    destFilePath = "./generate/vue/%s" % vueApiFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)
    # 复制文件
    cpRepoCmd = "cp ./template/vue/api_template.js %s" % destFilePath
    os.system(cpRepoCmd)

    query_field_loop_area = ""
    for field in fields:
        smallField = field["smallField"]
        desc = field["desc"]

        # chinese: filter.chinese,
        query_field_loop_area += '%s: filter.%s,\n\t\t' % (smallField, smallField)


    alter(destFilePath, "$query_field_loop_area$", query_field_loop_area)

    alter(destFilePath, "$XXXXXX$", bigHumpName)
    alter(destFilePath, "$xxxxxx$", smallHumpName)
    alter(destFilePath, "$routerGroup$", routerGroup)


def generateSQL(bigHumpName, smallHumpName, fields):
    # 目标文件
    destFilePath = "./generate/sql/%s" % sqlFileName
    # 清理文件
    delRepoCmd = "rm -rf %s " % destFilePath
    os.system(delRepoCmd)
    # 复制文件
    cpRepoCmd = "cp ./template/db_sql_template.sql %s" % destFilePath
    os.system(cpRepoCmd)

    table_field_loop_area = ""
    for field in fields:
        smallField = field["smallField"]
        dbType = field["type"]
        desc = field["desc"]

        # updated_user_nickname varchar(500) null comment '更新人名称',
        table_field_loop_area += '%s %s null comment \'%s\',\n\t' % (smallField, dbType, desc)

    alter(destFilePath, "$table_field_loop_area$", table_field_loop_area)
    alter(destFilePath, "$dbName$", dbName)
    alter(destFilePath, "$tableName$", dbTableName)
    alter(destFilePath, "$tableComment$", tableComment)

if __name__ == '__main__':
    # counterparty_contact
    # CounterpartyContact
    # counterpartyContact

    # 业务大名
    bigHumpName = "CounterpartyContact"
    # 业务小名
    smallHumpName = "counterpartyContact"
    # 业务名称
    bizName = "交易对手联系方式"


    # ====== 数据库相关 start 如果sql已经是别人生成好了, 无需修改下面变量,注释generateSQL即可 ======
    # 生成的文件名
    sqlFileName = "counterparty_contact.sql"
    # 库名
    dbName = "soms"
    # 表名
    dbTableName = "counterparty_contact"
    # 表的注释
    tableComment = "经营资质证书表"
    # ====== 数据库相关 end ======

    # ====== 后端相关 start ======
    # repo文件名
    repoFileName = "counterpartyContact.go"
    # thrift文件名
    thriftFileName = "counterpartyContact.thrift"
    # service文件名
    serviceFileName = "counterpartyContact.go"
    # bff-router 文件名
    bffRouterFileName = "counterpartyContact.go"
    # bff-handler 文件名
    bffHandlerFileName = "counterpartyContact.go"
    # ====== 后端相关 end ======

    # ====== 权限相关 start ======
    # gateway
    # 端口
    bffPort = "8036"
    # 路由组
    routerGroup = "soms"
    # 生成的gateway sql 的文件名
    gatewayFileName = "gateway_temp_counterparty_contact.sql"

    # role
    # 父模块名称
    parentModuleName = "商品管理"
    # 父模块编码
    parentModuleCode = "soms"
    # 当前角色节点编码
    roleNodeCode = "/soms/counterparty_contact"
    # 生成的 role sql 的文件名
    roleFileName = "role_temp_counterparty_contact.sql"
    # ====== 权限相关 end ======

    # ====== 前端相关 start ======
    # vue页面
    vueFileName = "counterpartyContact.vue"
    # vue store js
    vueStoreFileName = "store/counterpartyContact.js"
    # vue api js
    vueApiFileName = "api/counterpartyContact.js"
    # ====== 前端相关 end ======


    # 加载配置文件
    fields = load_json('./template/table_counterparty_contact.json')
    for kv in fields:
        print(kv["columnName"])
        print(kv["type"])
        print(kv["desc"])
    generateAppRepo(dbTableName, bigHumpName, smallHumpName, fields)
    generateAppThrift(fields, thriftFileName)
    generateAppService(fields)
    generateBffRouter(bigHumpName, smallHumpName, fields)
    generateBffHandle(bigHumpName, smallHumpName, fields)
    generateBffHandleStruct(bigHumpName, smallHumpName, fields)
    generateGateway(bigHumpName,smallHumpName, bffPort, bizName, routerGroup)
    generateRole(bigHumpName,smallHumpName, parentModuleName, parentModuleCode, bizName, routerGroup, roleNodeCode)
    generateVue(bigHumpName, smallHumpName, fields)
    #generateSQL(bigHumpName, smallHumpName, fields)
